package com.naja.auth2server.web;

import com.naja.auth2server.web.dto.RegisteredClientDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.UUID;

/**
 * @auther wangjianying
 * @date 2023/12/07 15:04
 */
@RestController()
@RequestMapping("/manage/client")
public class ManageClientController {
    @Autowired
    private RegisteredClientRepository registeredClientRepository;

    @PostMapping("/register")
    public String registerClient(@RequestBody RegisteredClientDto registeredClientDto) {
        RegisteredClient registeredClient = null;
        if (registeredClientDto == null) {
            registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
                    .clientId("messaging-client")
                    .clientSecret("{noop}secret")
                    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                    .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                    .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                    .redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
                    .redirectUri("http://127.0.0.1:8080/authorized")
                    .scope(OidcScopes.OPENID)
                    .scope(OidcScopes.PROFILE)
                    .scope("message.read")
                    .scope("message.write")
                    .clientSettings(ClientSettings.builder().requireAuthorizationConsent(false).build())
                    .build();
        } else {
            RegisteredClient.Builder builder = RegisteredClient.withId(UUID.randomUUID().toString())
                    .clientId(registeredClientDto.getClientId())
                    .clientSecret(registeredClientDto.getClientSecret());
            if (registeredClientDto.getClientAuthenticationMethods() != null) {
                for (Map<String, Object> clientAuthenticationMethod : registeredClientDto.getClientAuthenticationMethods()) {
                    builder.clientAuthenticationMethod(new ClientAuthenticationMethod((String) clientAuthenticationMethod.get("value")));
                }
            }
            if (registeredClientDto.getAuthorizationGrantTypes() != null) {
                for (Map<String, Object> authorizationGrantType : registeredClientDto.getAuthorizationGrantTypes()) {
                    builder.authorizationGrantType(new AuthorizationGrantType((String) authorizationGrantType.get("value")));
                }
            }
            if (registeredClientDto.getRedirectUris() != null) {
                for (String redirectUris : registeredClientDto.getRedirectUris()) {
                    builder.redirectUri(redirectUris);
                }
            }
            if (registeredClientDto.getScopes() != null) {
                for (String scope : registeredClientDto.getScopes()) {
                    builder.scope(scope);
                }
            }
            if (registeredClientDto.getClientSettings() != null) {
                ClientSettings settings = ClientSettings.builder().requireAuthorizationConsent((Boolean) registeredClientDto.getClientSettings().get("settings").get("require-authorization-consent")).build();
                builder.clientSettings(settings);
            }
            builder.tokenSettings(TokenSettings.builder().accessTokenFormat(OAuth2TokenFormat.REFERENCE).build());
            registeredClient = builder.build();
        }
        registeredClientRepository.save(registeredClient);
        return "ok";
    }

    @GetMapping("/test")
    public String test() {
        return "get";
    }

    @PostMapping("/test")
    public String testp() {
        return "post";
    }

}
